import scrapy
import re
from heroSpider.items import HeroItem, HeroStatsItem, HeroSkillsItem, RebonItem, SoulbindItem


def parse_multi_attr(item):
    head = list(filter(lambda x: x != "-" and x != '', [x.strip() for x in item.xpath('./text()').extract()]))
    tail = item.xpath('./a/@title').extract()
    if len(head) == len(tail):
        return [i + ' ' + j for i, j in zip(head, tail)]
    else:
        return head


def parse_rich_text(item):
    text = item.xpath('./text() | ./a/@title | ./b/text()').extract()
    return ' '.join(text).strip()


class HerosSpider(scrapy.Spider):
    name = 'heros'
    allowed_domains = ['fandom.com']
    start_urls = ['https://mightyparty.fandom.com/wiki/Hero_List']

    def parse(self, response):
        print('#### ok ####')
        rows = response.xpath('//table/tbody/tr')
        for row in rows:
            res = row.xpath('./td')
            if res:
                id = res[0].xpath('./b/text()').extract_first()
                name = res[1].xpath('./b/span/a/text()').extract_first()
                image = res[2].xpath('./a/image/@src').extract_first()
                rarity = res[3].xpath('./div/a/@title').extract_first()
                faction = res[4].xpath('./div/a/@title').extract_first()
                gender = res[5].xpath('./div/a/@title').extract_first()
                type = res[6].xpath('./div/a/@title').extract_first()
                yield HeroItem(
                    id=id,
                    name=name,
                    image=image,
                    rarity=rarity,
                    faction=faction,
                    gender=gender,
                    type=type
                )
                yield scrapy.Request('https://mightyparty.fandom.com/wiki/%s' % name,
                                     callback=self.parse_hero, meta={'hero': name})


    def parse_hero(self, response):
        hero = response.meta['hero']
        tables = response.xpath('//table[@class="wikitable"]')
        # hero stat
        tb_hero_stat = tables[1].xpath('./tbody/tr')[1:]
        star = None
        for row in tb_hero_stat:
            lvl_star = row.xpath('./th/text()').extract()
            if len(lvl_star) > 1:
                level = lvl_star[0]
                star = lvl_star[1][1:]
            else:
                level = lvl_star[0]
            row = row.xpath('./td')
            yield HeroStatsItem(
                hero=hero,
                level=level.strip(),
                star=star,
                atk=row[0].xpath('./text()').extract_first().strip(),
                hp=row[1].xpath('./text()').extract_first().strip(),
                bonus=parse_multi_attr(row[2]),
                might=row[3].xpath('./text()').extract_first().strip(),
                troops=row[4].xpath('./text()').extract_first().strip(),
                required_league=row[5].xpath('./text()').extract_first().strip(),
                level_requird=parse_multi_attr(row[6]),
                total_required=parse_multi_attr(row[7])
            )

        # hero skill
        tb_hero_skill = tables[2].xpath('./tbody/tr')[1:]
        star = None
        for row in tb_hero_skill:
            lvl_star = row.xpath('./th/text()').extract()
            if len(lvl_star) > 1:
                level = lvl_star[0]
                star = lvl_star[1][1:]
            else:
                level = lvl_star[0]
            item = {
                "hero": hero,
                "level": level,
                "star": star,
            }
            skills = row.xpath('./td')
            idx = 1
            for skill in skills:
                item['skill'+str(idx)] = parse_rich_text(skill)
                idx += 1
            yield HeroSkillsItem(**item)

        # soulbind
        tb_soulbind = tables[3].xpath('./tbody/tr')[1:]
        for row in tb_soulbind:
            soulbind = row.xpath('./th/text()').extract_first().strip()
            row = row.xpath('./td')
            yield SoulbindItem(
                hero=hero,
                soulbind=soulbind,
                required_heros=row[0].xpath('.//a/text()').extract(),
                required_level=row[1].xpath('./text()').extract_first().strip(),
                cost=parse_rich_text(row[2]),
                bonus=parse_rich_text(row[3]),
                might=row[4].xpath('./text()').extract_first().strip(),
                troop_strength=row[5].xpath('./text()').extract_first().strip(),
            )

        # reborn
        tb_reborn = tables[4].xpath('./tbody/tr')[1:]
        for row in tb_reborn:
            reborn = row.xpath('./th/text()').extract_first().strip()
            row = row.xpath('./td')
            yield RebonItem(
                hero=hero,
                reborn=reborn,
                required_level=row[0].xpath('./text()').extract_first().strip(),
                attack_bonus=parse_rich_text(row[1]),
                health_bonus=parse_rich_text(row[2]),
                skill_bonus=parse_rich_text(row[3]),
                might=row[4].xpath('./text()').extract_first().strip(),
                troop_strength=row[5].xpath('./text()').extract_first().strip(),
            )
